package com.heima.comment.service.impl;


import java.util.*;
import java.util.stream.Collectors;

import com.heima.comment.service.CommentHotService;
import com.heima.comment.service.CommentService;
import com.heima.common.exception.CustException;
import com.heima.feigns.UserFeign;

import com.heima.model.comment.dtos.CommentDTO;
import com.heima.model.comment.dtos.CommentLikeDTO;
import com.heima.model.comment.dtos.CommentSaveDTO;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentLike;
import com.heima.model.comment.vo.ApCommentVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.pojos.ApUser;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jsoup.helper.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class CommentServiceImpl implements CommentService {
    @Autowired
    UserFeign userFeign;
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    CommentHotService commentHotService;

    @Override
    public ResponseResult saveComment(CommentSaveDTO dto) {
//1.检查参数
        ApUser user = AppThreadLocalUtils.getUser();
        //                校验是否登录
        if (user == null) {
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN, "用户需要登录后操作");//1 需要登录后操作
        }

//        校验文章id   校验内容不为空  校验内容长度不能大于140个字符 (validated校验)

        //        2. 阿里云校验评论内容是否违规

//   ​    (简单:  此步不做      普通: 阿里云检测有问题提示      高级:  有问题不报异常，替换为**)

//        3. 远程查询当前登陆用户信息
        ResponseResult<ApUser> ApUserResult = userFeign.findUserById(user.getId());
        if (ApUserResult == null) {
            CustException.cust(AppHttpCodeEnum.PARAM_REQUIRE, "当前信息有误");//500 缺少参数
        }
//        4. 创建评论信息，并保存到mongo
        user = ApUserResult.getData();
        ApComment apComment = new ApComment();

        apComment.setAuthorId(user.getId());
        apComment.setAuthorName(user.getName());
        apComment.setImage(user.getImage());
        apComment.setContent(dto.getContent());
        apComment.setArticleId(dto.getArticleId());
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());
        apComment.setLikes(0);
        apComment.setReply(0);
        apComment.setType((short) 0);
        apComment.setFlag((short) 0);
        mongoTemplate.save(apComment);

        return ResponseResult.okResult();
    }

    /**
     * 点赞评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDTO dto) {
        //1. 参数校验
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN, "用户需要登录后操作");//1 需要登录后操作
        }
//   评论id不能为空  operation必须为 0  或  1

//2. 根据评论id查询评论数据， 为返回错误信息

//3. 如果是点赞操作 判断是否已经点赞
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if (apComment != null && dto.getOperation() == 0) {
            //更新评论的点赞数量
            apComment.setLikes(apComment.getLikes() + 1);
            mongoTemplate.save(apComment);

            //计算热点评论评论
            if (apComment.getLikes() >= 10 && apComment.getFlag().shortValue() == 0) {
                commentHotService.hotCommentExecutor(apComment);
            }

        if (apComment == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "当前评论不存在");
        }
//   点过赞提示 请勿重复点赞
        ApCommentLike apCommentLike = mongoTemplate.findOne(Query.query
                        (Criteria.where("authorId").is(user.getId())
                                .and("commentId").is(dto.getCommentId()))
                , ApCommentLike.class);
        Short operation = dto.getOperation();

        if (apCommentLike != null && operation.intValue() == 0) {
            CustException.cust(AppHttpCodeEnum.DATA_EXIST, "用户已点赞");//1003数据已存在
        }
        //   未点过赞   保存点赞信息到mongo
        if (operation.intValue() == 0) {
            apCommentLike = new ApCommentLike();
            apCommentLike.setAuthorId(user.getId());
            apCommentLike.setCommentId(apComment.getId());
            apCommentLike.setOperation(dto.getOperation());
            mongoTemplate.save(apCommentLike);
            //   并修改评论信息的点赞数量( + 1)
            apComment.setLikes(apComment.getLikes() + 1);
            mongoTemplate.save(apComment);

        } else {
            //4. 如果是取消点赞操作
            //   并修改评论信息的点赞数量( - 1) , 要判断下别减成负数
            apComment.setLikes(apComment.getLikes() <= 0 ? 0 : apComment.getLikes() - 1);
            mongoTemplate.save(apComment);
//   删除点赞信息
            mongoTemplate.remove(Query.query(Criteria.where("authorId").is(user.getId()).and("commentId").is(apComment.getId())), ApCommentLike.class);
        }
    }//5. 返回结果时，需要返回点赞点赞数量  返回的key要求必须是:  likes
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("likes", apComment.getLikes());
        return ResponseResult.okResult(resultMap);
    }
    /**
     * 根据文章id查询评论列表
     *
     * @param dto
     * @return
     */

    @Override
    public ResponseResult findByArticleId(CommentDTO dto) {
//> 1. 参数校验
        if (dto == null && dto.getArticleId() == null) {
            CustException.cust(AppHttpCodeEnum.PARAM_REQUIRE, "当前信息有误");
        }
        //>    校验size
        Integer size = dto.getSize();
        if (size == null || size <= 0) {
            size=10;
        }

//2 查询Mongo文章所有评论列表
        List<ApComment> apCommentList = null;

        // 判断当前是否是第一页评论
        if (dto.getIndex().intValue() == 1) {
            // 先查询热点评论集合  （最多5条） (条件: flag=1, 文章id, 点赞降序)
            Query query = Query.query(Criteria.where("articleId").is(dto.getArticleId()).and("flag").is(1))
                    .with(Sort.by(Sort.Direction.DESC, "likes")).limit(5);
            apCommentList = mongoTemplate.find(query, ApComment.class);
            if (CollectionUtils.isNotEmpty(apCommentList)) {
                // 新size = size - 热评数量
               size=size - apCommentList.size();
            }else {
                // 查询第一页剩余普通评论 (条件: 文章id, flag=0, 时间降序, limit:新size)
                /*List<ApComment> commonComments = mongoTemplate.find(getQuery(dto, size), ApComment.class);
                 */
                Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
                Query query1 = Query.query(Criteria.where("articleId").is(dto.getArticleId()).and("flag").is(0))
                        .limit(size).with(sort);
                List<ApComment> apCommentList1 = mongoTemplate.find(query1, ApComment.class);
                // 合并 热点评论  普通评论   热点list.addAll(普通list)
                apCommentList.addAll(apCommentList1);
            }
        } else {
            // 不是第一页直接查询普通评论
            // (条件: 文章id,flag=0,createdTime小于最小时间,时间降序,limit:size)
            Query query2 = Query.query(Criteria.where("articleId").is(dto.getArticleId())
                    .and("flag").is(0).and("createdTime").lt(dto.getMinDate())).limit(size)
                    .with(Sort.by(Sort.Direction.DESC, "createdTime"));
            mongoTemplate.find(query2, ApComment.class);
        }
        // ========================需要变更处 end =============================
        //3 封装查询结果
        ApUser user = AppThreadLocalUtils.getUser();
        //3.1 用户未登录 直接返回评论列表
        if (user == null) {
            return ResponseResult.okResult(apCommentList);
        }
        //3.2 用户登录，需要加载当前用户对评论点赞的列表
        List<ApCommentVo> apCommentVoList = new ArrayList<>();
        List<String> list = apCommentList.stream().map(comment -> comment.getId()).collect(Collectors.toList());
        // 查询 点赞批量列表 按照评论id 筛选
        List<ApCommentLike> apCommentLikes = mongoTemplate.find(
                Query.query(Criteria.where("commentId").in(list)
                        .and("authorId").is(user.getId()))
                , ApCommentLike.class);
// 遍历当前用户点赞列表 和当前评论列表
        if (CollectionUtils.isNotEmpty(apCommentList)
                && CollectionUtils.isNotEmpty(apCommentLikes)) {
            apCommentList.forEach(comment -> { //遍历所有文章列表ID
                ApCommentVo apCommentVo = new ApCommentVo();
                BeanUtils.copyProperties(comment, apCommentVo);
                //遍历当前用户点赞列表
                apCommentLikes.forEach(apCommentLike -> {
                    // 文章评论列表id 和 当前用户点赞评论列表id是否相等
                    if (comment.getId().equals(apCommentLike.getCommentId())) {
                        apCommentVo.setOperation((short) 0);
                    }
                });
                apCommentVoList.add(apCommentVo);
            });
            return ResponseResult.okResult(apCommentVoList);
        }
        return ResponseResult.okResult(apCommentList);
    }

}
